package handler

import (
	"common"
	"common/biz"
	"common/logs"
	"context"
	"core/repo"
	"core/service"
	"encoding/json"
	"framework/remote"
	"game/logic"
	"game/models/request"
	hall "hall/handler"
	"strconv"
	"time"
)

type CardHandler struct {
	gameService *service.GameService
	um          *logic.CardManager
	base        *hall.BaseHandler
}

func (h *CardHandler) RoomList(session *remote.Session, msg []byte) any {
	logs.Info("[Game] RoomList msg:%v", string(msg))
	uid, _ := strconv.Atoi(session.GetUid())
	if uid <= 0 {
		logs.Error("[Game] RoomList err:未获取到UID")
		return common.F(biz.InvalidUsers)
	}
	if err := h.base.Login(nil, uint(uid), session.GetSid()); err != nil {
		return common.F(err)
	}
	roomList := h.um.GetRoom(6)
	return common.S(roomList)
}

func (h *CardHandler) CreateRoom(session *remote.Session, msg []byte) any {
	logs.Info("[Game] CreateRoom msg:%v", string(msg))
	uid, _ := strconv.Atoi(session.GetUid())
	if uid <= 0 {
		logs.Error("[Game] CreateRoom err:未获取到UID")
		return common.F(biz.InvalidUsers)
	}
	if err := h.base.Login(nil, uint(uid), session.GetSid()); err != nil {
		return common.F(err)
	}
	var req request.CreateRoomReq
	if err := json.Unmarshal(msg, &req); err != nil {
		logs.Error("[Game]用户%d CreateRoom err:缺少参数 req=%v,err=%v", uid, req, err)
		return common.F(biz.RequestDataError)
	}
	ctx := context.TODO()
	userData, err := h.gameService.GameCardInfo(ctx, uint(uid), req.ID)
	if err != nil {
		return common.F(err)
	}
	if userData.Gold < req.GameRule.BaseScore {
		logs.Error("[Game]用户%d CreateRoom err:游戏币数量不足 req=%v", uid, req)
		return common.F(biz.GameRoomError)
	}
	// 组装规则
	h.upGameRule(ctx, req.ID, &req.GameRule)
	count := h.gameService.GameCardNotEnd(ctx, uint(uid))
	if count > 0 {
		return common.F(biz.GameNotEndError)
	}
	err = h.um.CreateRoom(session, &req, userData, h.gameService)
	if err != nil {
		return common.F(err)
	}
	return common.S(nil)
}

func (h *CardHandler) JoinRoom(session *remote.Session, msg []byte) any {
	logs.Info("[Game] JoinRoom msg:%v", string(msg))
	uid, _ := strconv.Atoi(session.GetUid())
	if uid <= 0 {
		logs.Error("[Game] JoinRoom err:未获取到UID")
		return common.F(biz.InvalidUsers)
	}
	if err := h.base.Login(nil, uint(uid), session.GetSid()); err != nil {
		return common.F(err)
	}
	var req request.JoinRoomReq
	if err := json.Unmarshal(msg, &req); err != nil {
		logs.Error("[Game]用户%d JoinRoom err:缺少参数 req=%v,err=%v", uid, req, err)
		return common.F(biz.RequestDataError)
	}
	ctx := context.TODO()
	userData, err := h.gameService.GameCardInfo(ctx, uint(uid), req.ID)
	if err != nil {
		return common.F(err)
	}
	count := h.gameService.GameCardNotEnd(ctx, uint(uid))
	if count > 0 {
		return common.F(biz.GameNotEndError)
	}
	err = h.um.JoinRoom(session, req.RoomID, userData, h.gameService)
	if err != nil {
		return common.F(err)
	}
	return common.S(nil)
}

func (h *CardHandler) CardLog(session *remote.Session, msg []byte) any {
	logs.Info("[Game] CardLog msg:%v", string(msg))
	uid, _ := strconv.Atoi(session.GetUid())
	if uid <= 0 {
		logs.Error("[Game] CardLog err:未获取到UID")
		return common.F(biz.InvalidUsers)
	}
	if err := h.base.Login(nil, uint(uid), session.GetSid()); err != nil {
		return common.F(err)
	}
	var req request.PageMsg
	if err := json.Unmarshal(msg, &req); err != nil {
		logs.Error("[Game]用户%d CardLog err:缺少参数 req=%v,err=%v", uid, req, err)
		return common.F(biz.RequestDataError)
	}
	ctx := context.TODO()
	count, data := h.gameService.CardLog(ctx, uint(uid), &req)
	return common.S(map[string]any{
		"count": count,
		"data":  data,
	})
}

// upGameRule 游戏规则
func (h *CardHandler) upGameRule(ctx context.Context, gameID uint, req *request.GameRule) {
	req.GameType = gameID
	conf := h.gameService.GetConf(ctx, gameID)
	for _, v := range *conf {
		if v.Name == "init_people_num" {
			val, _ := strconv.Atoi(v.Value)
			req.MinPlayerCount = val
			req.MaxPlayerCount = val
		} else if v.Name == "init_gold" {
			val, _ := strconv.Atoi(v.Value)
			req.InitGold = int64(val)
		} else if v.Name == "init_blood" {
			val, _ := strconv.Atoi(v.Value)
			req.InitBlood = int64(val)
		} else if v.Name == "init_level" {
			val, _ := strconv.Atoi(v.Value)
			req.InitLevel = int64(val)
		} else if v.Name == "level_max" {
			val, _ := strconv.Atoi(v.Value)
			req.LevelMax = int64(val)
		} else if v.Name == "gold_max" {
			val, _ := strconv.Atoi(v.Value)
			req.GoldMax = int64(val)
		} else if v.Name == "site_card_max_num" {
			val, _ := strconv.Atoi(v.Value)
			req.SiteCardMaxNum = int64(val)
		} else if v.Name == "hand_card_max_num" {
			val, _ := strconv.Atoi(v.Value)
			req.HandCardMaxNum = int64(val)
		} else if v.Name == "refresh_gold" {
			val, _ := strconv.Atoi(v.Value)
			req.RefreshGold = int64(val)
		} else if v.Name == "blood_loss_sub" {
			val, _ := strconv.Atoi(v.Value)
			req.BloodLossSub = int64(val)
		} else if v.Name == "card_second_hand_price" {
			val, _ := strconv.ParseFloat(v.Value, 64)
			req.CardSecondHandPrice = val
		} else if v.Name == "game_fee" {
			val, _ := strconv.ParseFloat(v.Value, 64)
			req.GameFee = val
		} else if v.Name == "room_not_prepare_sleep" {
			val, _ := strconv.Atoi(v.Value)
			req.WaitReady = time.Duration(val)
		} else if v.Name == "selete_card_sleep" {
			val, _ := strconv.Atoi(v.Value)
			req.SelectCardSleep = time.Duration(val)
		} else if v.Name == "champion_rate" {
			val, _ := strconv.ParseFloat(v.Value, 64)
			req.ChampionRate = val
		} else if v.Name == "runner_rate" {
			val, _ := strconv.ParseFloat(v.Value, 64)
			req.RunnerRate = val
		} else if v.Name == "third_place_rate" {
			val, _ := strconv.ParseFloat(v.Value, 64)
			req.ThirdPlaceRate = val
		} else if v.Name == "operate_sleep" {
			val, _ := strconv.Atoi(v.Value)
			req.OperateSleep = time.Duration(val)
		} else if v.Name == "refresh_card" {
			val, _ := strconv.Atoi(v.Value)
			req.RefreshCard = int64(val)
		} else if v.Name == "each_level_gold_rate" {
			val, _ := strconv.Atoi(v.Value)
			req.EachLevelGoldRate = int64(val)
		} else if v.Name == "condition_buy_skill_level" {
			val, _ := strconv.Atoi(v.Value)
			req.ConditionBuySkillLevel = int64(val)
		} else if v.Name == "start_time" {
			req.StartTime = v.Value
		} else if v.Name == "end_time" {
			req.EndTime = v.Value
		}
	}
}

func NewCardHandler(r *repo.Manager, um *logic.CardManager) *CardHandler {
	return &CardHandler{
		gameService: service.NewGameService(r),
		um:          um,
		base:        hall.NewBaseHandler(r),
	}
}
